package net.ryian.push.impl;

import java.util.Map;
import java.util.Map.Entry;

import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.umeng.push.android.AndroidBroadcast;
import com.umeng.push.android.AndroidCustomizedcast;
import com.umeng.push.android.AndroidGroupcast;
import com.umeng.push.android.AndroidUnicast;
import com.umeng.push.ios.IOSBroadcast;
import com.umeng.push.ios.IOSCustomizedcast;
import com.umeng.push.ios.IOSGroupcast;
import com.umeng.push.ios.IOSUnicast;
import net.ryian.push.IPushService;
import net.ryian.push.PushConfig;
import net.ryian.push.PushNotification;

public class UmengPushService implements IPushService {

	private Logger logger = Logger.getLogger(UmengPushService.class);

	@Override
	public void pushAndroid(String apiKey, String secretKey,
			PushNotification message) {
		sendAndroidBroadcast(apiKey, secretKey, message);
	}

	@Override
	public void pushIOS(String apiKey, String secretKey,
			PushNotification message) {
		sendIOSBroadcast(apiKey, secretKey, message);
	}

	private void sendAndroidBroadcast(String apiKey, String secretKey,
			PushNotification message) {
		AndroidBroadcast broadcast = new AndroidBroadcast();
		broadcast.setAppMasterSecret(secretKey);
		try {
			broadcast.setPredefinedKeyValue("appkey", apiKey);
			broadcast
					.setPredefinedKeyValue(
							"timestamp",
							Integer.toString((int) (System.currentTimeMillis() / 1000)));
			broadcast.setPredefinedKeyValue("ticker",
					"Android broadcast ticker");
			broadcast.setPredefinedKeyValue("title", message.getTitle());
			broadcast.setPredefinedKeyValue("text", message.getDescription());
			broadcast.setPredefinedKeyValue("description",message.getDescription());
			broadcast.setPredefinedKeyValue("after_open", "go_app");
			broadcast.setPredefinedKeyValue("display_type", "message");
			broadcast.setPredefinedKeyValue("custom", "aa");
			// TODO Set 'production_mode' to 'false' if it's a test device.
			// For how to register a test device, please see the developer doc.
			broadcast.setPredefinedKeyValue("production_mode",
					String.valueOf(!PushConfig.INSTANCE.isDevmode()));
			// Set customized fields
			if (message.getExtraInfo() != null) {
				for (Entry<String, String> entry : message.getExtraInfo()
						.entrySet()) {
					broadcast.setExtraField(entry.getKey(), entry.getValue());
				}
			}
			broadcast.send();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void sendIOSBroadcast(String apiKey, String secretKey,
			PushNotification message) {

		IOSBroadcast broadcast = new IOSBroadcast();
		broadcast.setAppMasterSecret(secretKey);
		try {
			broadcast.setPredefinedKeyValue("appkey", apiKey);
			broadcast
					.setPredefinedKeyValue(
							"timestamp",
							Integer.toString((int) (System.currentTimeMillis() / 1000)));

			broadcast.setPredefinedKeyValue("alert", message.getTitle());
			broadcast.setPredefinedKeyValue("badge", 0);
			broadcast.setPredefinedKeyValue("sound", "chime");
			// TODO set 'production_mode' to 'true' if your app is under
			// production
			// mode
			broadcast.setPredefinedKeyValue("production_mode",
					String.valueOf(!PushConfig.INSTANCE.isDevmode()));
			// Set customized fields
			if (message.getExtraInfo() != null) {
				for (Entry<String, String> entry : message.getExtraInfo()
						.entrySet()) {
					broadcast.setCustomizedField(entry.getKey(),
							entry.getValue());
				}
			}
			broadcast.send();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void pushAndroidGroupCast(String apiKey, String secretKey,
			PushNotification message, String tag) throws Exception {
		AndroidGroupcast groupcast = new AndroidGroupcast();
		groupcast.setAppMasterSecret(secretKey);
		groupcast.setPredefinedKeyValue("appkey", apiKey);
		groupcast.setPredefinedKeyValue("timestamp",
				Integer.toString((int) (System.currentTimeMillis() / 1000)));
		/*
		 * TODO Construct the filter condition: "where": { "and": [
		 * {"tag":"test"}, {"tag":"Test"} ] }
		 */
		JSONObject filterJson = new JSONObject();
		JSONObject whereJson = new JSONObject();
		JSONArray tagArray = new JSONArray();
		String[] tags = tag.split(";");
		for (int i = 0, len = tags.length; i < len; i++) {
			JSONObject jsonTag = new JSONObject();
			jsonTag.put("tag", tags[i]);
			tagArray.add(jsonTag);
		}
		whereJson.put("or", tagArray);
		filterJson.put("where", whereJson);

		Map<String, String> extraInfo = message.getExtraInfo();
		if (extraInfo != null) {
			for (Entry<String, String> entry : extraInfo.entrySet()) {
				groupcast.setExtraField(entry.getKey(), entry.getValue());
			}
		}

		groupcast.setPredefinedKeyValue("filter", filterJson);
		groupcast.setPredefinedKeyValue("ticker", "Android groupcast ticker");
		groupcast.setPredefinedKeyValue("title", message.getTitle());
		groupcast.setPredefinedKeyValue("custom", message.getTitle());
		groupcast.setPredefinedKeyValue("text", message.getDescription());
		groupcast.setPredefinedKeyValue("description", message.getDescription());
		groupcast.setPredefinedKeyValue("after_open", "go_app");
		groupcast.setPredefinedKeyValue("display_type", "message");
		groupcast.setPredefinedKeyValue("production_mode",
				String.valueOf(!PushConfig.INSTANCE.isDevmode()));
		groupcast.send();

	}

	public void pushIOSGroupCast(String apiKey, String secretKey,
			PushNotification message, String tag) throws Exception {

		IOSGroupcast groupcast = new IOSGroupcast();
		groupcast.setAppMasterSecret(secretKey);
		groupcast.setPredefinedKeyValue("appkey", apiKey);
		groupcast.setPredefinedKeyValue("timestamp",
				Integer.toString((int) (System.currentTimeMillis() / 1000)));
		/*
		 * TODO Construct the filter condition: "where": { "and": [
		 * {"tag":"iostest"} ] }
		 */
		JSONObject filterJson = new JSONObject();
		JSONObject whereJson = new JSONObject();
		JSONArray tagArray = new JSONArray();
		String[] tags = tag.split(";");
		for (int i = 0, len = tags.length; i < len; i++) {
			JSONObject jsonTag = new JSONObject();
			jsonTag.put("tag", tags[i]);
			tagArray.add(jsonTag);
		}
		whereJson.put("or", tagArray);
		filterJson.put("where", whereJson);
		logger.info(filterJson.toString());

		// Set filter condition into rootJson
		groupcast.setPredefinedKeyValue("filter", filterJson);
		groupcast.setPredefinedKeyValue("alert", message.getDescription());
		groupcast.setPredefinedKeyValue("description",message.getDescription());
		groupcast.setPredefinedKeyValue("badge", 0);
		groupcast.setPredefinedKeyValue("sound", "chime");
		groupcast.setPredefinedKeyValue("production_mode",
				String.valueOf(!PushConfig.INSTANCE.isDevmode()));
		Map<String, String> extraInfo = message.getExtraInfo();
		if (extraInfo != null) {
			logger.info("=============customizedfield============");
			for (Entry<String, String> entry : extraInfo.entrySet()) {
				logger.info(entry.getKey() + ":" + entry.getValue());
				groupcast.setCustomizedField(entry.getKey(), entry.getValue());
			}
		}
		groupcast.send();
	}

	@Override
	public void pushAndroid(String apiKey, String secretKey,
			PushNotification message, String tag) {
		try {
			pushAndroidGroupCast(apiKey, secretKey, message, tag);
		} catch (Exception e) {
			logger.error("pushAndroid:", e);
		}
		// sendAndroidCustomizedcast(apiKey, secretKey, message, tag);
	}

	@Override
	public void pushIOS(String apiKey, String secretKey,
			PushNotification message, String tag) {
		try {
			pushIOSGroupCast(apiKey, secretKey, message, tag);
		} catch (Exception e) {
			logger.error("pushIOS:", e);
		}
	}

	private void sendAndroidCustomizedcast(String apiKey, String secretKey,
			PushNotification message, String alias,String aliasType) {
		AndroidCustomizedcast customizedcast = new AndroidCustomizedcast();
		customizedcast.setAppMasterSecret(secretKey);
		try {
			customizedcast.setPredefinedKeyValue("appkey", apiKey);
			customizedcast
					.setPredefinedKeyValue(
							"timestamp",
							Integer.toString((int) (System.currentTimeMillis() / 1000)));
			// TODO Set your alias here, and use comma to split them if there
			// are
			// multiple alias.
			// And if you have many alias, you can also upload a file containing
			// these alias, then
			// use file_id to send customized notification.
			customizedcast.setPredefinedKeyValue("alias", alias);
			// TODO Set your alias_type here
			customizedcast.setPredefinedKeyValue("alias_type", aliasType);
			customizedcast.setPredefinedKeyValue("ticker",
					"Android customizedcast ticker");
			customizedcast.setPredefinedKeyValue("title", message.getTitle());
			customizedcast.setPredefinedKeyValue("custom", message.getTitle());
			customizedcast.setPredefinedKeyValue("text",
					message.getDescription());
			customizedcast.setPredefinedKeyValue("after_open", "go_app");
			customizedcast.setPredefinedKeyValue("display_type", "message");

			// TODO Set 'production_mode' to 'false' if it's a test device.
			// For how to register a test device, please see the developer doc.
			customizedcast.setPredefinedKeyValue("production_mode",
					String.valueOf(!PushConfig.INSTANCE.isDevmode()));
			customizedcast.send();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	private void sendIOSCustomizedcast(String apiKey, String secretKey,
			PushNotification message, String tag) {
		IOSCustomizedcast customizedcast = new IOSCustomizedcast();
		customizedcast.setAppMasterSecret(secretKey);
		try {
			customizedcast.setPredefinedKeyValue("appkey", apiKey);
			customizedcast
					.setPredefinedKeyValue(
							"timestamp",
							Integer.toString((int) (System.currentTimeMillis() / 1000)));
			// TODO Set your alias here, and use comma to split them if there
			// are
			// multiple alias.
			// And if you have many alias, you can also upload a file containing
			// these alias, then
			// use file_id to send customized notification.
			customizedcast.setPredefinedKeyValue("alias", tag);
			// TODO Set your alias_type here
			customizedcast.setPredefinedKeyValue("alias_type", "tag");
			customizedcast.setPredefinedKeyValue("alert",
					message.getDescription());
			customizedcast.setPredefinedKeyValue("description",message.getDescription());

			customizedcast.setPredefinedKeyValue("badge", 0);
			customizedcast.setPredefinedKeyValue("sound", "chime");
			// TODO set 'production_mode' to 'true' if your app is under
			// production
			// mode
			customizedcast.setPredefinedKeyValue("production_mode",
					String.valueOf(!PushConfig.INSTANCE.isDevmode()));
			customizedcast.send();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private void sendAndroidUnicast(String apiKey, String secretKey,
			PushNotification message, String token) throws Exception {
		AndroidUnicast unicast = new AndroidUnicast();
		unicast.setAppMasterSecret(secretKey);
		unicast.setPredefinedKeyValue("appkey", apiKey);
		unicast.setPredefinedKeyValue("timestamp", Integer.toString((int) (System.currentTimeMillis() / 1000)));
		// TODO Set your device token
		unicast.setPredefinedKeyValue("device_tokens", token);
		unicast.setPredefinedKeyValue("ticker", "Android unicast ticker");
		unicast.setPredefinedKeyValue("custom", message.getTitle());
		unicast.setPredefinedKeyValue("title", message.getTitle());
		unicast.setPredefinedKeyValue("text", message.getDescription());
		unicast.setPredefinedKeyValue("after_open", "go_app");
		unicast.setPredefinedKeyValue("display_type", "message");
		// TODO Set 'production_mode' to 'false' if it's a test device.
		// For how to register a test device, please see the developer doc.
		unicast.setPredefinedKeyValue("production_mode", String.valueOf(!PushConfig.INSTANCE.isDevmode()));
		// Set customized fields
		Map<String, String> extraInfo = message.getExtraInfo();
		if (extraInfo != null) {
			for (Entry<String, String> entry : extraInfo.entrySet()) {
				unicast.setExtraField(entry.getKey(), entry.getValue());
			}
		}
		unicast.send();
	}
	
	private void sendIOSUnicast(String apiKey, String secretKey,
			PushNotification message, String token) throws Exception {
		IOSUnicast unicast = new IOSUnicast();
		unicast.setAppMasterSecret(secretKey);
		unicast.setPredefinedKeyValue("appkey", apiKey);
		unicast.setPredefinedKeyValue("timestamp", Integer.toString((int) (System.currentTimeMillis() / 1000)));
		// TODO Set your device token
		unicast.setPredefinedKeyValue("device_tokens", token);
		unicast.setPredefinedKeyValue("alert", message.getDescription());
		unicast.setPredefinedKeyValue("badge", 0);
		unicast.setPredefinedKeyValue("sound", "chime");
		// TODO set 'production_mode' to 'true' if your app is under production
		// mode
		unicast.setPredefinedKeyValue("production_mode", String.valueOf(!PushConfig.INSTANCE.isDevmode()));
		// Set customized fields
		Map<String, String> extraInfo = message.getExtraInfo();
		if (extraInfo != null) {
			for (Entry<String, String> entry : extraInfo.entrySet()) {
				unicast.setCustomizedField(entry.getKey(), entry.getValue());
			}
		}
		unicast.send();
	}

	@Override
	public void pushAndroidToSingle(String apiKey, String secretKey,
			PushNotification message, String token) {
		try {
			sendAndroidUnicast(apiKey, secretKey, message, token);
		} catch (Exception e) {
			logger.error("pushAndroidToSingle error:",e);
		}
	}

	@Override
	public void pushIOSToSingle(String apiKey, String secretKey,
			PushNotification message, String token) {
		try {
			sendIOSUnicast(apiKey, secretKey, message, token);
		} catch (Exception e) {
			logger.error("pushIOSToSingle error:",e);
		}
	}

}
